using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Diagnostics;
using System.Drawing.Drawing2D;
namespace BPMN.MainWindow
{
    public abstract class Gateways : FlowObject
    {
        public GatewaysType gatewaysType;
        public GatewaysType GatewaysType
        {
            get
            {
                return GatewaysType;
            }
            set
            {
                GatewaysType = value;
            }
        }
        public Gateways()
        {
            Location = new PointF(0, 0);
            Size = new SizeF((float)100.0, (float)100);
            BoundingBox = new RectangleF(Location, Size);
            State = FigureState.Editing;
        }
        public Gateways(PointF location, SizeF size)
        {
            this.Location = location;
            this.Size = size;
            PointF LocationBoundingBox = new PointF(location.X - size.Width / 2, location.Y - size.Height / 2);
            SizeF SizeBoundingBox = new SizeF(size.Height, size.Width);
            BoundingBox = new RectangleF(LocationBoundingBox, SizeBoundingBox);
            State = FigureState.Resizing;
            updateHotSpots();
            this.Path = new GraphicsPath();
            Path.StartFigure(); 
            PointF p1 = new PointF(BoundingBox.Location.X   + Size.Width, BoundingBox.Location.Y  + Size.Height / 2);
            PointF p2 = new PointF(BoundingBox.Location.X + Size.Width / 2, BoundingBox.Location.Y );
            PointF p3 = new PointF(BoundingBox.Location.X , BoundingBox.Location.Y +  Size.Height / 2);
            PointF p4 = new PointF(BoundingBox.Location.X  + Size.Width / 2, BoundingBox.Location.Y + Size.Height);
            PointF[] points = new PointF[5];
            points[0] = p1;
            points[1] = p2;
            points[2] = p3;
            points[3] = p4;
            points[4] = p1;
            Path.AddLines(points);
            Path.CloseFigure();
            Region = new Region(Path);
        }
        public Gateways(PointF location, SizeF size, FigureState state)
        {
            this.Location = location;
            this.Size = size;
            PointF LocationBoundingBox = new PointF(location.X - size.Width / 2, location.Y - size.Height / 2);
            SizeF SizeBoundingBox = new SizeF(size.Height, size.Width);
            BoundingBox = new RectangleF(LocationBoundingBox, SizeBoundingBox);
            State = FigureState.Resizing;
            updateHotSpots();
            this.Path = new GraphicsPath();
            Path.StartFigure();
            PointF p1 = new PointF(BoundingBox.Location.X + Size.Width, BoundingBox.Location.Y + Size.Height / 2);
            PointF p2 = new PointF(BoundingBox.Location.X + Size.Width / 2, BoundingBox.Location.Y);
            PointF p3 = new PointF(BoundingBox.Location.X, BoundingBox.Location.Y + Size.Height / 2);
            PointF p4 = new PointF(BoundingBox.Location.X + Size.Width / 2, BoundingBox.Location.Y + Size.Height);
            PointF[] points = new PointF[5];
            points[0] = p1;
            points[1] = p2;
            points[2] = p3;
            points[3] = p4;
            points[4] = p1;
            Path.AddLines(points);
            Path.CloseFigure();
            Region = new Region(Path);
            this.State = state;
        }
        public override void Draw(Graphics graphics, Pen pen, Brush brush, PointF offset)
        {
            switch (this.State)
            {
                case FigureState.Editing:
                    Color aux = (brush as SolidBrush).Color;
                    (brush as SolidBrush).Color = Variables.HotspotUnused;
                    foreach (HotSpot hotspot in objects)
                    {
                        graphics.FillEllipse(brush, hotspot.Location.X - Variables.HotspotResize.Width / 2, hotspot.Location.Y - Variables.HotspotResize.Height / 2, Variables.HotspotResize.Width, Variables.HotspotResize.Height);
                    }
                    (brush as SolidBrush).Color = aux;
                    break;
            }
            /*
             *  GraphicsPath gp=new GraphicsPath();
            PointF []points = new PointF[5];
            points[0] = new PointF(BoundingBox.X + Size.Width / 2 + offset.X, BoundingBox.Y + offset.Y);
            points[1] = new PointF(BoundingBox.X + Size.Width  + offset.X, BoundingBox.Y + offset.Y+Size.Height/2);
            points[2] = new PointF(BoundingBox.X + Size.Width / 2 + offset.X, BoundingBox.Y + offset.Y + Size.Height);
            points[3] = new PointF(BoundingBox.X  + offset.X, BoundingBox.Y + offset.Y+Size.Height/2);
            points[4] = new PointF(BoundingBox.X + Size.Width / 2 + offset.X, BoundingBox.Y + offset.Y);
            gp.AddLines(points);
            graphics.DrawPath(pen, gp);
             */
            PointF p1 = new PointF(BoundingBox.Location.X + offset.X + Size.Width, BoundingBox.Location.Y + offset.Y + Size.Height / 2);
            PointF p2 = new PointF(BoundingBox.Location.X + offset.X + Size.Width / 2, BoundingBox.Location.Y + offset.Y);
            PointF p3 = new PointF(BoundingBox.Location.X + offset.X, BoundingBox.Location.Y + offset.Y + Size.Height / 2);
            PointF p4 = new PointF(BoundingBox.Location.X + offset.X + Size.Width / 2, BoundingBox.Location.Y + offset.Y + Size.Height);
            PointF[] points = new PointF[5];
            points[0] = p1;
            points[1] = p2;
            points[2] = p3;
            points[3] = p4;
            points[4] = p1;
            graphics.DrawLines(pen, points);
            switch (this.State)
            {
                case FigureState.Editing:
                    Color aux = (brush as SolidBrush).Color;
                    (brush as SolidBrush).Color = Variables.HotspotUnused;
                    foreach (HotSpot hotspot in objects)
                    {
                        graphics.FillEllipse(brush, hotspot.Location.X - Variables.HotspotResize.Width / 2, hotspot.Location.Y - Variables.HotspotResize.Height / 2, Variables.HotspotResize.Width, Variables.HotspotResize.Height);
                    }
                    (brush as SolidBrush).Color = aux;
                    break;
            }
        }
        public override void updateHotSpots()
        {
            objects.Clear();
            List<PointF> points = new List<PointF>();
            points.Add(new PointF(BoundingBox.Location.X + Size.Width / 2, BoundingBox.Location.Y));
            points.Add(new PointF(BoundingBox.Location.X + Size.Width / 2, BoundingBox.Location.Y + Size.Height));
            points.Add(new PointF(BoundingBox.Location.X, BoundingBox.Location.Y + Size.Height / 2));
            points.Add(new PointF(BoundingBox.Location.X + Size.Width, BoundingBox.Location.Y + Size.Height / 2));
            for (int i = 0; i < points.Count; i++)
            {
                objects.Add(new HotSpot(points[i]));
            }
        }
    }
/*
    public abstract class GatewayXor : Gateways
    {
        public GatewayXor()
        {
            Location = new PointF(0, 0);
            Size = new SizeF((float)100.0, (float)100);
            BoundingBox = new RectangleF(Location, Size);
            State = FigureState.Editing;
        }        public GatewayXor(Point location, SizeF size, Rectangle boundingBox, FigureState state)
        {
            this.Location = location;
            this.Size = size;
            PointF LocationBoundingBox = new PointF(location.X - size.Width / 2, location.Y - size.Height / 2);
            SizeF SizeBoundingBox = new SizeF(size.Height, size.Width);
            BoundingBox = new RectangleF(LocationBoundingBox, SizeBoundingBox);
            State = FigureState.Resizing;
            updateHotSpots();
            this.Path = new GraphicsPath();
            Path.StartFigure();
           PointF p1 = new PointF(BoundingBox.Location.X + offset.X + Size.Width, BoundingBox.Location.Y + offset.Y + Size.Height / 2);
            PointF p2 = new PointF(BoundingBox.Location.X + offset.X + Size.Width / 2, BoundingBox.Location.Y + offset.Y);
            PointF p3 = new PointF(BoundingBox.Location.X + offset.X, BoundingBox.Location.Y + offset.Y + Size.Height / 2);
            PointF p4 = new PointF(BoundingBox.Location.X + offset.X + Size.Width / 2, BoundingBox.Location.Y + offset.Y + Size.Height);
            PointF[] points = new PointF[5];
            points[0] = p1;
            points[1] = p2;
            points[2] = p3;
            points[3] = p4;
            points[4] = p1;
            Path.AddLines(points);
            Path.CloseFigure();
            Region = new Region(Path);
        }
        public GatewayXor(PointF location, SizeF size):base()
        {
           
            
        }

    }*/
    public class GatewayOr : Gateways
    {

       public GatewayOr():base()
       {
       }
        public GatewayOr(PointF location, SizeF size):base(location,  size)
        {
        }
        public GatewayOr(PointF location, SizeF size, FigureState state):base( location,  size,  state)
        {
        }
        public override void Draw(Graphics graphics, Pen pen, Brush brush, PointF offset)
        {
            base.Draw(graphics, pen, brush, offset);
            graphics.FillEllipse(Variables.DrawingBrush, Location.X + offset.X - Size.Width / 3 + 1, Location.Y + offset.Y - Size.Height / 3 + 1, (float)Size.Width * (float)0.6, (float)Size.Height * (float)0.6);
            graphics.FillEllipse(brush, Location.X + offset.X - Size.Width / 5, Location.Y + offset.Y - Size.Height / 5, Size.Width *(float)0.4, Size.Height*(float)0.4);
            
            //graphics.DrawEllipse(pen, Location.X + offset.X -Size.Width / 3,Location.Y + offset.Y - Size.Height / 3 , Size.Width/2,Size.Height / 3);
        }

    }
    public abstract class GatewayXor : Gateways
    {
        public GatewayXor():base()
        {
         
       }
        public GatewayXor(PointF location, SizeF size)  : base(location, size)
        {
        }
        public GatewayXor(PointF location, SizeF size, FigureState state):base( location,  size,  state)
        {
        }
        public override void Draw(Graphics graphics, Pen pen, Brush brush, PointF offset)
        {
            base.Draw(graphics, pen, brush, offset);
        }
    }
    public class GatewayComplex : Gateways
    {
       public GatewayComplex():base()
        {
         
       }
        public GatewayComplex(PointF location, SizeF size):base(location,  size)
        {
        }
         public GatewayComplex(PointF location, SizeF size, FigureState state):base( location,  size,  state)
        {
        }
        public override void Draw(Graphics graphics, Pen pen, Brush brush, PointF offset)
        {
            base.Draw(graphics, pen, brush, offset);
            Pen p = new Pen(Variables.DrawingBrush, Size.Width / 11);
            graphics.DrawLine(p, Location.X + offset.X - Size.Width / 5, Location.Y + offset.Y - Size.Height / 5, Location.X + offset.X + Size.Width / 5, Location.Y + offset.Y + Size.Height / 5);
            graphics.DrawLine(p, Location.X + offset.X - Size.Width / 5, Location.Y + offset.Y + Size.Height / 5, Location.X + offset.X + Size.Width / 5, Location.Y + offset.Y - Size.Height / 5);
            graphics.DrawLine(p, Location.X + offset.X , Location.Y + offset.Y - Size.Height / 4, Location.X + offset.X , Location.Y + offset.Y + Size.Height / 4);
            graphics.DrawLine(p, Location.X + offset.X - Size.Width / 4, Location.Y + offset.Y , Location.X + offset.X + Size.Width / 4, Location.Y + offset.Y );



        }

    }
    public class GatewayXorDatabased : GatewayXor
    {
        public GatewayXorDatabased():base()
        {
         
       }
        public GatewayXorDatabased(PointF location, SizeF size): base(location, size)
        {
        }
         public GatewayXorDatabased(PointF location, SizeF size, FigureState state):base( location,  size,  state)
        {
        }
        public override void Draw(Graphics graphics, Pen pen, Brush brush, PointF offset)
        {
            base.Draw(graphics, pen, brush, offset);
        }
        
    }
    public class GatewayXorDatabasedCancel : GatewayXorDatabased
    {
        public GatewayXorDatabasedCancel()
            : base()
        {

        }
        public GatewayXorDatabasedCancel(PointF location, SizeF size)
            : base(location, size)
        {
        }
        public GatewayXorDatabasedCancel(PointF location, SizeF size, FigureState state)
            : base(location, size, state)
        {
        }
        public override void Draw(Graphics graphics, Pen pen, Brush brush, PointF offset)
        {
            base.Draw(graphics, pen, brush, offset);
            Pen p = new Pen(Variables.DrawingBrush, Size.Width / 8);
            graphics.DrawLine(p, Location.X + offset.X - Size.Width / 5, Location.Y + offset.Y - Size.Height / 5, Location.X + offset.X + Size.Width / 5, Location.Y + offset.Y + Size.Height / 5);
            graphics.DrawLine(p, Location.X + offset.X - Size.Width / 5, Location.Y + offset.Y + Size.Height / 5, Location.X + offset.X + Size.Width / 5, Location.Y + offset.Y - Size.Height / 5);
        }

    }
    public class GatewayXorEventbased : GatewayXor
    {
       public GatewayXorEventbased():base()
        {
         
       }
        public GatewayXorEventbased(PointF location, SizeF size):base(location,  size)
        {
        }
        public GatewayXorEventbased(PointF location, SizeF size, FigureState state)
            : base(location, size, state)
        {
        }
        public override void Draw(Graphics graphics, Pen pen, Brush brush, PointF offset)
        {
            base.Draw(graphics, pen, brush, offset);
            graphics.DrawEllipse(pen, Location.X + offset.X-Size.Width/4 ,Location.Y + offset.Y-Size.Height/4  , Size.Width/2,Size.Height / 2);
            graphics.DrawEllipse(pen, Location.X + offset.X - Size.Width / 3 + 1, Location.Y + offset.Y - Size.Height / 3 + 1, (float)Size.Width * (float)0.6, (float)Size.Height * (float)0.6);
            //graphics.DrawEllipse(pen, Location.X + offset.X -Size.Width / 3,Location.Y + offset.Y - Size.Height / 3 , Size.Width/2,Size.Height / 3);
            GraphicsPath gp = new GraphicsPath();
            PointF[] points = new PointF[4];
            points[0] = new PointF(Location.X + offset.X, Location.Y + offset.Y - Size.Height / 4);
            points[1] = new PointF(Location.X + offset.X + Size.Width / 6, Location.Y + offset.Y + Size.Height / 10);
            points[2] = new PointF(Location.X + offset.X - Size.Width / 6, Location.Y + offset.Y + Size.Height / 10);
            points[3] = new PointF(Location.X + offset.X, Location.Y + offset.Y - Size.Height / 4);
            gp.AddLines(points);
            graphics.FillPath(Variables.DrawingBrush, gp);
            GraphicsPath gp2 = new GraphicsPath();
            PointF[] points2 = new PointF[4];
            points2[0] = new PointF(Location.X + offset.X, Location.Y + offset.Y + Size.Height / 4);
            points2[1] = new PointF(Location.X + offset.X + Size.Width / 6, Location.Y + offset.Y - Size.Height / 10);
            points2[2] = new PointF(Location.X + offset.X - Size.Width / 6, Location.Y + offset.Y - Size.Height / 10);
            points2[3] = new PointF(Location.X + offset.X, Location.Y + offset.Y + Size.Height / 4);
            gp2.AddLines(points2);
            graphics.FillPath(Variables.DrawingBrush, gp2);

        }
        
    }
    public class GatewayAnd : GatewayXor
    {
        public GatewayAnd()
            : base()
        {

        }
        public GatewayAnd(PointF location, SizeF size)
            : base(location, size)
        {
        }
        public GatewayAnd(PointF location, SizeF size, FigureState state)
            : base(location, size, state)
        {
        }
        public override void Draw(Graphics graphics, Pen pen, Brush brush, PointF offset)
        {
            base.Draw(graphics, pen, brush, offset);
            Pen p = new Pen(Variables.DrawingBrush, Size.Width / 11);
            graphics.DrawLine(p, Location.X + offset.X, Location.Y + offset.Y - Size.Height / 4, Location.X + offset.X, Location.Y + offset.Y + Size.Height / 4);
            graphics.DrawLine(p, Location.X + offset.X - Size.Width / 4, Location.Y + offset.Y, Location.X + offset.X + Size.Width / 4, Location.Y + offset.Y);

            

        }

    }

}
